package org.example.design.strategy.guess;

import java.util.Random;

/**
 * @author huangshen
 * @version 0
 * @description ProbStrategy
 * @since 2022/2/8 9:14
 */
public class ProbStrategy implements Strategy {

    private final Random random;
    /**
     * 上一次出的手势值
     */
    private int prevHandValue = 0;
    /**
     * 当前处理的手势值
     */
    private int currentHandValue = 0;

    /**
     * 胜利历史记录  history[上一局出的手势][这一局出的手势]
     * 例 history[0][0]:两局分别出石头、石头时胜利的次数
     */
    private final int[][] history = {
            {1, 1, 1},
            {1, 1, 1},
            {1, 1, 1}
    };

    public ProbStrategy(int seed) {
        random = new Random(seed);
    }

    /**
     * 根据过去胜率概率计算下一局出的手势
     * history为过去胜利局数记录数组，如
     *      history[0][0],history[0][1],history[0][2] 代表上一局出石头，下一局出石头、剪子、布时的胜利局数
     * 如果history[0][0] = 3,history[0][1] = 5,history[0][2] = 7 则下一局出什么就会以 石头：剪子：布 3:5:7来决定，
     * 然后在0-15（不含15）之间取一个随机数
     * @return Hand
     */
    @Override
    public Hand nextHand() {
        // 获取上一局所出手势总胜局数后在其中随机一个数
        int bet = random.nextInt(getSum(currentHandValue));
        int handValue;
        // 获取下一局出的手势
        if (bet < history[currentHandValue][0]) {
            handValue = 0;
        } else if (bet < history[currentHandValue][0] + history[currentHandValue][1]) {
            handValue = 1;
        } else {
            handValue = 2;
        }

        prevHandValue = currentHandValue;
        currentHandValue = handValue;
        return Hand.getHand(handValue);
    }

    private int getSum(int hv) {
        int sum = 0;
        for (int i = 0; i < 3; i++) {
            sum +=  history[hv][i];
        }
        return sum;
    }

    @Override
    public void study(boolean win) {
        if (win) {
            // 如果赢了 当前手势胜率提升
            history[prevHandValue][currentHandValue] ++;
        } else {
            // 如果输了 其他手势的胜率提升
            history[prevHandValue][(currentHandValue + 1) % 3] ++;
            history[prevHandValue][(currentHandValue + 2) % 3] ++;
        }
    }
}
